﻿using System;
using System.Data;
using System.Diagnostics;
using System.Linq;

using TestDatabaseFirst.Entities;

namespace TestDatabaseFirst
{
    static class TestProtocols
    {
        private static void LoadAll()
        {
            using (var db = new GsTestDBEntities())
            {
                var protocols = from p in db.Protocols
                                orderby p.LoadOrder
                                select p;

                int index = 0;
                foreach (Protocol p in protocols)
                {
                    ++index;
                    Console.WriteLine("[{0}] Id={1} Acronym='{2}'", index, p.ID, p.Acronym);
                }
            }
        }

        private static void AddNew()
        {
            using (var db = new GsTestDBEntities())
            {
                int count = 3;
                for (int index = 0; index < count; index++)
                {
                    // we don't need to specify ID property
                    // because that column is auto-increment
                    var newP = new Protocol
                    {
                        Acronym = "TestAcronym",
                        Name = "TestName",
                        LoadOrder = 100
                    };
                    Debug.Assert(newP.ID == 0, "NOT SET YET,WAITING FOR DB TO SET");

                    // by calling "Add", internally
                    // the state will be changed into "added"
                    // and "INSERT" statements will be generated
                    db.Protocols.Add(newP);
                }

                int changed = db.SaveChanges();
                Debug.Assert(changed == count);
                Console.WriteLine("{0} rows added", changed);

                // chekanote: EF will set the generated PrimaryKey back to the entity
                var newlyAdded = (from p in db.Protocols
                                  where p.Acronym.StartsWith("Test")
                                  select p).ToArray();
                newlyAdded.All(p => p.ID > 0);
                foreach (var newP in newlyAdded)
                {
                    Console.WriteLine("added protocol has Id={0}", newP.ID);
                }
            }
        }

        private static void SelectByKey()
        {
            using (var db = new GsTestDBEntities())
            {
                int existingKey = 1;
                var found = db.Protocols.Find(existingKey);
                Debug.Assert(found.ID == existingKey);
                Console.WriteLine("Found: Id={0},Acronym='{1}'", found.ID, found.Acronym);

                int nonExistKey = -1;
                var nonExist = db.Protocols.Find(nonExistKey);
                Debug.Assert(nonExist == null);
                Console.WriteLine("!!! Protocol with Id={0} NOT found", nonExistKey);
            }
        }

        private static void Edit()
        {
            using (var db = new GsTestDBEntities())
            {
                var testProtocols = from p in db.Protocols
                                    where p.Acronym.StartsWith("Test")
                                    select p;

                int index = 0;
                foreach (Protocol p in testProtocols)
                {
                    ++index;
                    p.Acronym = string.Format("Test-{0}-edit", index);
                    p.Name = string.Format("testname-{0}", index*10);
                    p.LoadOrder += index;

                    // chekanote: we don't need to specify "Modified" state explicitly
                    // db.Entry(p).State = EntityState.Modified;
                }

                var changed = db.SaveChanges();
                Console.WriteLine("{0} rows have been changed.", changed);
            }// using
        }

        private static void Delete()
        {
            using (var db = new GsTestDBEntities())
            {
                var testProtocols = from p in db.Protocols
                                    where p.Acronym.StartsWith("Test")
                                    select p;
                foreach (Protocol p in testProtocols)
                {
                    db.Entry(p).State = EntityState.Deleted;
                }

                var changed = db.SaveChanges();
                Console.WriteLine("{0} rows affected", changed);
            }
        }

        private static void Navigate()
        {
            using (var db = new GsTestDBEntities())
            {
                var c37p118 = db.Protocols.First(p => p.Acronym.Equals("IeeeC37_118V1"));

                int index = 0;
                foreach (var device in c37p118.Devices)
                {
                    ++index;
                    Console.WriteLine("[{0}] AccessId={1} Acronym='{2}'", index, device.AccessID, device.Acronym);
                }
            }
        }

        public static void TestMain()
        {
            // LoadAll();
            // AddNew();
            // SelectByKey();
            Edit();
            // Delete();
            // Navigate();
        }// testmain
    }
}
